/*
Copyright SecureKey Technologies Inc. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package event

import (
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/common/options"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/ichain/events/client"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/ichain/events/deliverclient"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/ichain/events/deliverclient/seek"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/providers/context"
	"git.cloud.inspur.com/ichain/ichain-sdk-go/pkg/providers/ichain"
	"github.com/pkg/errors"
)

// Client
// @Description: 事件订阅客户端
type Client struct {
	ichain.EventService // 事件订阅服务
	permitBlockEvents   bool
	fromBlock           uint64
	seekType            seek.Type
}

func New(chainProvider context.ChainProvider, opts ...ClientOption) (*Client, error) {

	chainContext, err := chainProvider()
	if err != nil {
		return nil, errors.WithMessage(err, "failed to create chain context")
	}

	eventClient := Client{}

	for _, param := range opts {
		err1 := param(&eventClient)
		if err1 != nil {
			return nil, errors.WithMessage(err, "option failed")
		}
	}

	if chainContext.ChainService() == nil {
		return nil, errors.New("chain service not initialized")
	}

	var es ichain.EventService
	if eventClient.permitBlockEvents {
		var opts []options.Opt
		opts = append(opts, client.WithBlockEvents())
		if eventClient.seekType != "" {
			opts = append(opts, deliverclient.WithSeekType(eventClient.seekType))
			if eventClient.seekType == seek.FromBlock {
				opts = append(opts, deliverclient.WithBlockNum(eventClient.fromBlock))
			}
		}
		es, err = chainContext.ChainService().EventService(opts...)
	} else {
		es, err = chainContext.ChainService().EventService()
	}

	if err != nil {
		return nil, errors.WithMessage(err, "event service creation failed")
	}

	eventClient.EventService = es

	return &eventClient, nil
}
